﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;
using System.Collections.Generic;
using System.Windows.Browser;

namespace FloorDesigner
{
    [TemplateVisualState(Name = TableControl._Normal, GroupName = TableControl.NormalStates)]
    [TemplateVisualState(Name = TableControl._MouseOver, GroupName = TableControl.NormalStates)]
    [TemplateVisualState(Name = TableControl._Disabled, GroupName = TableControl.NormalStates)]
    [TemplateVisualState(Name = TableControl._DragStarted, GroupName = TableControl.DraggingStates)]
    [TemplateVisualState(Name = TableControl._Dropped, GroupName = TableControl.DraggingStates)]
    [TemplateVisualState(Name = TableControl._ContainerEnter, GroupName = TableControl.ContainerStates)]
    [TemplateVisualState(Name = TableControl._ContainerExit, GroupName = TableControl.ContainerStates)]
    
    public class TableControl : ContentControl
    {
        public event EventHandler<CopiedEventArgs<TableControl>> CopiedElement;
        public event EventHandler<DroppedEventArgs> Dropped;
        public event EventHandler<DragStartedEventArgs> DragStarted;
        public event EventHandler<DraggingEventArgs> Dragging;
        public event EventHandler<ContainerEventArgs<TableControl>> ContainerEnter;
        public event EventHandler<ContainerEventArgs<TableControl>> ContainerExit;

        public UserControl MainPage { get; set; }
        public bool IsNew { get; set; }
        public bool IsRactangle { get; set; }
        public bool IsOccupied { get; set; }

        public bool AllowCopy
        {
            get { return (bool)GetValue(AllowCopyProperty); }
            set { SetValue(AllowCopyProperty, value); }
        }
        public static readonly DependencyProperty AllowCopyProperty =
            DependencyProperty.Register("AllowCopy",typeof(bool),typeof(TableControl), new PropertyMetadata(OnChangeVisualStatePropertyChanged));

        public bool OnceCopy
        {
            get { return (bool)GetValue(OnceCopyProperty); }
            set { SetValue(OnceCopyProperty, value); }
        }
        public static readonly DependencyProperty OnceCopyProperty =
            DependencyProperty.Register("OnceCopy", typeof(bool), typeof(TableControl), new PropertyMetadata(OnChangeVisualStatePropertyChanged));

        private static void OnChangeVisualStatePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TableControl source = d as TableControl;
            Debug.Assert(source != null, "The source needs to be an instance of TableControl!");
            source.ChangeVisualState();
        }

        private const string NormalStates = "NormalStates";
        private const string DraggingStates = "DraggingStates";
        private const string ContainerStates = "ContainerStates";
        private const string _Normal = "Normal";
        private const string _MouseOver = "MouseOver";
        private const string _Disabled = "Disabled";
        private const string _DragStarted = "DragStarted";
        private const string _Dropped = "Dropped";
        private const string _ContainerEnter = "ContainerEnter";
        private const string _ContainerExit = "ContainerExit";

        LayoutManager _layoutManager;
        Image _dragImage;
        TextBlock _TableNo;
        bool mouseOver;

        public LayoutManager FloorDesigner { get { return this._layoutManager; } }
        
        // table image for drag drop
        public Image DragImage { get { return this._dragImage; } }
        public TextBlock TableNo { get { return this._TableNo; } }
        public bool DragImageVisibility = true; // visibility of table image 
        public bool TableNoVisibility = true; // visibility of table image 
        
        
        public IEnumerable<Panel> AllowedDropContainers { get; set; }

        public TableControl()
        {
            DefaultStyleKey = typeof(TableControl);
        }

        public override void OnApplyTemplate()
        {
            if (HtmlPage.IsEnabled)
            {
                // set image template 
                _dragImage = this.GetTemplateChild("imgdrag") as Image;
                if (_dragImage != null)
                {
                    _dragImage.Visibility = System.Windows.Visibility.Visible; // set default visibility 
                    if (DragImageVisibility == false) _dragImage.Visibility = System.Windows.Visibility.Collapsed; 
                    
                }

                // Set table name 

                _TableNo = this.GetTemplateChild("tableID") as System.Windows.Controls.TextBlock;
                if (_TableNo != null)
                {
                    _TableNo.Text = Convert.ToString(this.Content);
                    if (TableNoVisibility == false) _TableNo.Visibility = System.Windows.Visibility.Collapsed; 
                }
                

                base.OnApplyTemplate();

                this._layoutManager = new LayoutManager(this, this.AllowedDropContainers, this.AllowCopy, this.OnceCopy);

                AttachEvents(this);
            }
        }

        private void AttachEvents(TableControl control)
        {
            control.MouseEnter += new MouseEventHandler(control_MouseEnter);
            control.MouseLeave += new MouseEventHandler(control_MouseLeave);
            control.IsEnabledChanged += new DependencyPropertyChangedEventHandler(control_IsEnabledChanged);
            
            control.FloorDesigner.CopiedElement += new EventHandler<CopiedEventArgs<FrameworkElement>>(layoutManager_CopiedElement);
            control.FloorDesigner.Dropped += new EventHandler<DroppedEventArgs>(layoutManager_Dropped);
            control.FloorDesigner.DragStarted += new EventHandler<DragStartedEventArgs>(layoutManager_DragStarted);
            control.FloorDesigner.Dragging += new EventHandler<DraggingEventArgs>(layoutManager_Dragging);
            control.FloorDesigner.ContainerEnter += new EventHandler<ContainerEventArgs<FrameworkElement>>(layoutManager_ContainerEnter);
            control.FloorDesigner.ContainerExit += new EventHandler<ContainerEventArgs<FrameworkElement>>(layoutManager_ContainerExit);

            // Drag drop by table 
            // control.MouseLeftButtonDown += new MouseButtonEventHandler(control._layoutManager.StartDragging);
            
            // To allow drag drop by Image 
            if (control.DragImage != null) control.DragImage.MouseLeftButtonDown += new MouseButtonEventHandler(control._layoutManager.StartDragging);
        }

        public virtual void ChangeVisualState()
        {
            switch (this.IsEnabled)
            {
                case true:
                    VisualStateManager.GoToState(this, TableControl._Normal, true);
                    break;
                case false:
                    VisualStateManager.GoToState(this, TableControl._Disabled, true);
                    break;
            }

            // Mouse over will be only recognized when element is enabled
            if (this.IsEnabled && this.mouseOver)
            {
                VisualStateManager.GoToState(this, TableControl._MouseOver, true);
            }
        }


        void control_MouseEnter(object sender, MouseEventArgs e)
        {
            this.mouseOver = true;

            ChangeVisualState();
        }

        void control_MouseLeave(object sender, MouseEventArgs e)
        {
            this.mouseOver = false;

            ChangeVisualState();
        }

        void control_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            ChangeVisualState();
        }

        void layoutManager_CopiedElement(object sender, CopiedEventArgs<FrameworkElement> e)
        {
            if (this.CopiedElement != null)
                this.CopiedElement(this, new CopiedEventArgs<TableControl>((TableControl)e.ShapeTool, (TableControl)e.TableElement));
        }

        void layoutManager_Dropped(object sender, DroppedEventArgs e)
        {
            var droppedElement = (TableControl)e.TableElement;
            if (droppedElement.OnceCopy) droppedElement.AllowCopy = false;

            //VisualStateManager.GoToState(this, TableControl._Dropped, true);
            
            if (this.Dropped != null) this.Dropped(this, e);
        }

        void layoutManager_DragStarted(object sender, DragStartedEventArgs e)
        {
            //VisualStateManager.GoToState(this, TableControl._DragStarted, true);

            if (this.DragStarted != null) this.DragStarted(this,e);
        }        

        void layoutManager_Dragging(object sender, DraggingEventArgs e)
        {
            if (this.Dragging != null) this.Dragging(this, e);
        }

        void layoutManager_ContainerEnter(object sender, ContainerEventArgs<FrameworkElement> e)
        {
            //VisualStateManager.GoToState(this, TableControl._ContainerEnter, true);

            if (this.ContainerEnter != null) this.ContainerEnter( this, new ContainerEventArgs<TableControl>((TableControl)e.TableElement,e.Container));
        }

        void layoutManager_ContainerExit(object sender, ContainerEventArgs<FrameworkElement> e)
        {
            //VisualStateManager.GoToState(this, TableControl._ContainerExit, true);

            if (this.ContainerExit != null) this.ContainerExit(this, new ContainerEventArgs<TableControl>((TableControl)e.TableElement, e.Container));
        }

    }
}
